package com.pubinfo.passbook.engine;

import com.pubinfo.passbook.common.entity.TEngineComputeChain;
import com.pubinfo.passbook.common.entity.TPassbook;
import com.pubinfo.passbook.common.exception.ServiceException;
import com.pubinfo.passbook.common.mapper.TSubsidiaryInfoMapper;
import com.pubinfo.passbook.common.model.bo.witeoff.CityInfo;
import com.pubinfo.passbook.common.model.bo.witeoff.subitem.MedicineOnJobOrRetireSubitem;
import com.pubinfo.passbook.common.model.dto.witeoff.MedicineOnJobOrRetireDTO;
import com.pubinfo.passbook.common.model.ruler.PayInformation;
import com.pubinfo.passbook.common.service.engine.EngineComputeChainService;
import com.pubinfo.passbook.common.service.master.TPassbookService;
import com.pubinfo.passbook.common.service.ruler.CheckService;
import com.pubinfo.passbook.common.service.ruler.InformationService;
import com.pubinfo.passbook.common.service.ruler.impl.CheckServiceImpl;
import com.pubinfo.passbook.engine.result.MedicineComputeResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;

/**
 * 引擎计算接入部分
 *
 * @author zhouch
 * @date 2022/3/22 9:03
 */
@Service("ruleEngineCheckServiceImpl")
@Slf4j
public class RuleEngineCheckServiceImpl extends CheckServiceImpl implements CheckService {

    @Resource
    RuleEngineEntrance engineEntrance;

    @Resource
    EngineComputeChainService chainService;

    @Resource
    TPassbookService passbookService;

    @Resource
    InformationService informationService;

    @Resource
    TSubsidiaryInfoMapper infoMapper;

    /**
     * 报账计算 (引擎版)
     *
     * @param jobDTO
     * @return
     */
    @Override
    public BigDecimal countWriteoff(MedicineOnJobOrRetireDTO jobDTO, Boolean isFront) {
        //    jobDTO.setIsNeedAudit(true);
        TPassbook passbook = this.passbookService.getPassbookById(jobDTO.getInvoiceIds()).get(0);
        CityInfo info = this.infoMapper.findCityInfoByNsrsbh(passbook.getNsrsbh());
        if (info == null) {
            throw new ServiceException("没有找到区县信息.");
        }

        BigDecimal sum = new BigDecimal(0);

        String districtName = info.getDistrictName();

        //查询区县参数集
        PayInformation payInformation = this.informationService.informationFromPassbook(jobDTO.getInvoiceIds());
        String idNo = passbook.getPayerPartyCode(); //报账人的身份证号
        jobDTO.setIsSpecial(isSpecialDiseases(districtName, idNo));
        jobDTO.setIsSpecialUser(isSpecialUser(districtName, idNo));
        List<MedicineOnJobOrRetireSubitem> lineItems = jobDTO.getLineItems();

        //查询区县参数集
        BigDecimal outpatientDepartmentSum = new BigDecimal(0);
        BigDecimal outpatientDepartmentTotalAmount = new BigDecimal(0);
        BigDecimal hospitalizationSum = new BigDecimal(0);
        BigDecimal hospitalizationTotalAmount = new BigDecimal(0);

        // 根据地区ID查询所属计算链
        TEngineComputeChain chainInfo = chainService.getByDistrictID(info.getDisId());
        if (chainInfo == null) {
            throw new ServiceException("该区县还没有绑定任何计算链.");
        }

        // 数据和计算链ID交给引擎执行计算
        MedicineComputeResult engineComputeResult = engineEntrance.executeMedicineComputeChain(jobDTO, chainInfo.getId());

        engineComputeResult.pushMsgToHead("地区: "
                + info.getCityName() + "-" + districtName);

        BigDecimal reimburseSum = engineComputeResult.getResult();
        Boolean isNeedAudit = engineComputeResult.isNeedAudit();
        String detalis = engineComputeResult.messageToString("|");

        if ("330601".equals(passbook.getClassCode())) {
            outpatientDepartmentSum = outpatientDepartmentSum.add(reimburseSum);
            outpatientDepartmentTotalAmount = outpatientDepartmentTotalAmount.add(payInformation.getTotalAmount());
            jobDTO.setOutpatientDepartmentNub(jobDTO.getOutpatientDepartmentNub() + 1);
        } else {
            hospitalizationSum = hospitalizationSum.add(reimburseSum);
            hospitalizationTotalAmount = hospitalizationTotalAmount.add(payInformation.getTotalAmount());
            jobDTO.setHospitalizationNub(jobDTO.getHospitalizationNub() + 1);
        }
        payInformation.setReimbursableSum(reimburseSum);
        sum = sum.add(reimburseSum);
        outpatientDepartmentSum = outpatientDepartmentSum.setScale(2, RoundingMode.HALF_UP);
        outpatientDepartmentTotalAmount = outpatientDepartmentTotalAmount.setScale(2, RoundingMode.HALF_UP);
        hospitalizationSum = hospitalizationSum.setScale(2, RoundingMode.HALF_UP);
        hospitalizationTotalAmount = hospitalizationTotalAmount.setScale(2, RoundingMode.HALF_UP);
        jobDTO.setOutpatientDepartmentSum(outpatientDepartmentSum);
        jobDTO.setOutpatientDepartmentTotalAmount(outpatientDepartmentTotalAmount);
        jobDTO.setHospitalizationSum(hospitalizationSum);
        jobDTO.setHospitalizationTotalAmount(hospitalizationTotalAmount);

        //如果map中包含-0.0000999 ，则说明有些票据没有数据，则走人工审核
        jobDTO.setIsNeedAudit(isNeedAudit);
        jobDTO.setDetalis(detalis);

        //计算结果保留2位小数
        sum = sum.setScale(2, RoundingMode.HALF_UP);
        jobDTO.getPayInformations().add(payInformation);
        //   witeoffService
        for (MedicineOnJobOrRetireSubitem subitem : lineItems) {
            subitem.setSum(sum);
            subitem.setPriceSum(sum);
        }
        return sum;
    }

}
